package com.bbcare.comm;

import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.commons.io.IOUtils;

public class HttpUtil {
    private static Log log = LogFactory.getLog(HttpUtil.class);

    public static String postDataText(String url, Map<String, Object> msg) throws Exception {
        String result = null;
        PostMethod method = null;
        try {
            assertMsgNotNull(msg.toString());

            long begin = System.currentTimeMillis();
            HttpClient httpClient = new HttpClient();
            httpClient.getParams().setContentCharset("UTF-8");
            httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");

            // 增加超时时间限制
            iniTimeOut(httpClient);

            int mapSize = msg.size();
            if (0 == mapSize) {
                throw new Exception("待发送的报文为空，请核实！");
            }
            NameValuePair[] nvpArr = new NameValuePair[mapSize];
            Iterator<String> iter = msg.keySet().iterator();
            String key = "";
            int i = 0;
            while (iter.hasNext()) {
                key = iter.next();
                nvpArr[i] = new NameValuePair(key, "" + msg.get(key));
                i++;
            }

            method = new PostMethod(url);
            method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
            method.setRequestBody(nvpArr);
            log.warn("准备发送目标URL为:" + method.getURI());
            log.warn("入参：" + msg.toString());
            httpClient.executeMethod(method);

            InputStream in = method.getResponseBodyAsStream();
            result = IOUtils.toString(in, "utf-8");
            IOUtils.closeQuietly(in);

            int statu_code = method.getStatusLine().getStatusCode();
            assertResultSuccess(statu_code);

            log.warn("响应报文为：" + result);
            log.warn("发送请求,完成,耗时:" + (System.currentTimeMillis() - begin) + "毫秒");
        } catch (Exception e) {
            log.error("对端接口发送失败！", e);
            throw e;
        } finally {
            if (method != null) {
                method.releaseConnection();
            }
        }
        return result;
    }

    public static String postData(String url, String msg) throws Exception {
        String result = null;
        PostMethod method = null;
        try {
            assertMsgNotNull(msg);

            long begin = System.currentTimeMillis();
            log.debug("发送请求,开始:==>>" + msg);
            HttpClient httpClient = new HttpClient();

            // 增加超时时间限制
            iniTimeOut(httpClient);

            method = new PostMethod(url);
            StringRequestEntity entity = new StringRequestEntity(msg, "application/json", "utf-8");
            method.setRequestEntity(entity);
            httpClient.executeMethod(method);
            log.warn("准备发送目标URL为:" + method.getURI());

            InputStream in = method.getResponseBodyAsStream();
            result = IOUtils.toString(in, "utf-8");
            IOUtils.closeQuietly(in);

            int statu_code = method.getStatusLine().getStatusCode();

            log.debug("响应报文为：" + result);
            log.warn("发送请求,完成,耗时:" + (System.currentTimeMillis() - begin));

            assertResultSuccess(statu_code);
        } catch (Exception e) {
            log.error("对端接口发送失败！", e);
            throw e;
        } finally {
            if (method != null) {
                method.releaseConnection();
            }
        }
        return result;
    }

    /**
     * 增加超时时间限制
     * 
     * @author DemonLee
     * @date 2017.5.29
     *
     * @param httpClient
     */
    private static void iniTimeOut(HttpClient httpClient) {
        int conAndSoTimeOut = 30000;// default 30 seconds
        String timeOut = PropertiesUtils.getProperty("HTTPConTimeOut");
        if (null != timeOut && !"".equals(timeOut)) {
            conAndSoTimeOut = Integer.parseInt(timeOut);
        }
        log.debug("超时设定为：" + conAndSoTimeOut);
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(conAndSoTimeOut);
        httpClient.getHttpConnectionManager().getParams().setSoTimeout(conAndSoTimeOut);
        httpClient.getParams().setSoTimeout(conAndSoTimeOut);
    }

    private static void assertMsgNotNull(String msg) throws Exception {
        if (StringUtils.isBlank(msg)) {
            log.warn("待发送的报文为空，请核实！");
            throw new Exception("待发送的报文为空，请核实！");
        }
    }

    private static void assertResultSuccess(int statu_code) throws Exception {
        if (statu_code == 200 || statu_code == 204) {
        } else {
            log.error("调用对端接口响应错误,响应码为" + statu_code);
            throw new Exception("调用对端接口响应错误,响应码为" + statu_code);
        }
    }

}
